//system API wrapper
// $Id: sys_api.cpp 412 2010-03-27 12:01:54Z Oleg.Bulychov $

#include "stdafx.h"

#include "src/heo/include/sys_api.h"

#if defined(_WIN32)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <direct.h>
#include <io.h>

#else

//TODO better detection of pthread
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <sched.h>

#endif

namespace sys_api
{

void Yield_Thread()
{
#if defined(_WIN32)

    ::SwitchToThread();

#else

    ::sched_yield();

#endif

}

bool Is_Slash(char ch)
{
#if defined(_WIN32)
    return '/' == ch || '\\' == ch;
#else
    return '/' == ch;
#endif
}

bool Dir_Exist(char const* szPath)
{
#if defined(_WIN32)
    DWORD dw = ::GetFileAttributesA(szPath);
    return dw != INVALID_FILE_ATTRIBUTES && (dw & FILE_ATTRIBUTE_DIRECTORY);
#else
    struct stat st = {};
    return stat(szPath, &st) == 0;
#endif
}

inline bool Is_Dot_Path(std::string const& path)
{
    return path == "." || path == "..";
}

inline bool Ensure_Dir(std::string const& path)
{
    if(!Dir_Exist(path.c_str()))
    {
        if (Is_Dot_Path(path))
            return false;
#if defined(_WIN32)
        ::CreateDirectoryA(path.c_str(), NULL);
#else
        mkdir(path.c_str(), 0777);
#endif
    }
    return true;
} 

bool Create_Dir_Recursive(char const* szPath)
{
    std::string path(szPath);
    ASSERT_(path.length() > 0);
    if (!path.length())
        return false;
    if(Is_Slash(path[path.length() - 1]))
        path.resize(path.length() - 1);

    for(size_t i = 0; i < path.length(); ++i)
    {
        if(Is_Slash(path[i]))
        {
            char tmp = path[i];
            path[i] = '\0';
            if (!Ensure_Dir(path))
                return false;
            path[i] = tmp;
        }
    }
    return Ensure_Dir(path);
}

void Path_Append(std::string& s, char const* szName)
{
    if (s.length() && !Is_Slash(s[s.length() - 1]))
        s += '/';//:_WIN32 eat it too
    s += szName;
}


}

//EOF!
